
import { SelectFileOrFolder } from '@inbiz/setters';
import { Checkbox, DatePicker, Form, Input, Radio, Select, Space, Switch, InputNumber, ConfigProvider } from 'antd';
import cn from 'classnames';
import moment from 'moment';
import {
  useMemo,
  forwardRef,
  ForwardRefRenderFunction,
  ReactElement,
  useCallback,
  useEffect,
  useImperativeHandle,
  useRef,
  useState,
} from 'react';
import { GlobalRegistry } from '@inbiz/core';
import { TextWidget, getMessage } from '@inbiz/react';
import BelongDirectory from '@inbiz/basic/BelongDirectory'
import { ConditionItemType, SchemaOption } from '../../../../designer/conditionsSchema';
import { useInbiz } from '../../../../store/hooks/useInbiz';
import { useConfigEventsApi } from '../../../../store/hooks/useSearchPropsState';
import { useSearchUIState } from '../../../../store/hooks/useSearchUIState'
import MemberSelect from '@components/form/grade/EformMemberSelect/preview/web';
import ItemWithRemoveButton from './ItemWithRemoveButton'
import { commonLang } from '@inbiz/utils';
import { getFiletypes } from '../../service'
import { formatTypes } from '../SmallPanelView/SmallPanelAdvancedSearch/utils'
type SelectFolderProps = Parameters<typeof SelectFileOrFolder>[0];

// 数字框
export const NumberItem = ({
  value,
  onChange,
}: {
  value?: SchemaOption;
  onChange?: (value: SchemaOption) => void;
}) => {
  const [min, setMin] = useState('');
  const [max, setMax] = useState('');
  const onChangeRef = useRef(onChange);
  onChangeRef.current = onChange;
  const valueRef = useRef(value);
  valueRef.current = value;

  const onMinChange = useCallback((e) => {
    setMin(e.target.value);
  }, []);

  const onMaxChange = useCallback((e) => {
    setMax(e.target.value);
  }, []);

  const [defaultMin = '', defaultMax = ''] = (value?.value || '').split(',');

  useEffect(() => {
    if ((min || max) && valueRef.current) {
      onChangeRef.current?.({
        ...valueRef.current,
        value: `${min || ''},${max || ''}`,
      });
    }
  }, [min, max]);

  return (
    <div style={{ display: 'flex', alignItems: 'center' }}>
      <Input value={defaultMin} onChange={onMinChange} style={{ textAlign: 'center' }} />
      <span>~</span>
      <Input
        value={defaultMax}
        onChange={onMaxChange}
        className="site-input-right"
        style={{
          textAlign: 'center',
        }}
      />
    </div>
  );
};

interface Props {
  fields: SchemaOption[];
  defaultFields: SchemaOption[];
  onRemoveHandle: (field: SchemaOption) => void;
  style?: 'style1' | 'style2';
  searchEngineData: any
}
export interface InterfaceProps {
  onSubmit: () => Promise<Record<string, ConditionItemType>>;
  reset: () => void;
  setValues: (values: Record<string, ConditionItemType>) => void;
}

type Option = ConditionItemType['value'];
export const CustomCheckBox = ({
  value,
  onChange,
}: {
  value?: SchemaOption;
  onChange?: (value: SchemaOption) => void;
}) => {
  const onChangeRef = useRef(onChange);
  onChangeRef.current = onChange;
  const valueRef = useRef(value);
  valueRef.current = value;

  const onChangeHandle = useCallback(
    (checkedValue) => {
      const nextItems = valueRef.current?.options?.filter((item) =>
        checkedValue.includes(item.value),
      );
      if (nextItems && valueRef.current) {
        onChange?.({
          ...valueRef.current,
          value: nextItems,
        });
      }
    },
    [onChange],
  );

  const selectedValues = useMemo(() => {
    if (!value?.value) return;

    return value.value.map((item: Option) => item.value);
  }, [value?.value]);

  return (
    <Checkbox.Group value={selectedValues} style={{ width: '100%' }} onChange={onChangeHandle}>
      <Space direction="vertical">
        {(value?.options || []).map((item) => {
          return <Checkbox value={item.value}>{item.text}</Checkbox>;
        })}
      </Space>
    </Checkbox.Group>
  );
};

export const CustomRadio = ({
  value,
  onChange,
}: {
  value?: SchemaOption;
  onChange?: (value: SchemaOption) => void;
}) => {
  const onChangeRef = useRef(onChange);
  onChangeRef.current = onChange;
  const valueRef = useRef(value);
  valueRef.current = value;

  const onChangeHandle = useCallback(
    (checkedValue) => {
      const nextItem = valueRef.current?.options?.find?.(
        (item) => item.value === checkedValue.target.value,
      );
      if (nextItem && valueRef.current) {
        onChange?.({
          ...valueRef.current,
          value: [nextItem],
        });
      }
    },
    [onChange],
  );

  return (
    <Radio.Group
      value={value?.value?.[0]?.value}
      style={{ width: '100%' }}
      onChange={onChangeHandle}
    >
      <Space direction="vertical">
        {(value?.options || []).map((item) => {
          return <Radio value={item.value}>{item.text}</Radio>;
        })}
      </Space>
    </Radio.Group>
  );
};

export const CustomSelect = ({
  value,
  onChange,
  mode,
  extnameOptions
}: {
  mode?: 'multiple' | 'tags' | undefined;
  value?: SchemaOption;
  onChange?: (value: SchemaOption) => void;
}) => {
  
  const onChangeRef = useRef(onChange);
  onChangeRef.current = onChange;
  const valueRef = useRef(value);
  valueRef.current = value;
  if (value?.key == 'fileextname') {
    valueRef.current = {...value, options: extnameOptions}
  }

  const onChangeHandle = useCallback(
    (checkedValue) => {
      if (mode === 'multiple') {
        const nextItems = valueRef.current?.options?.filter((item) =>
          checkedValue.includes(item.value),
        );
        if (nextItems && valueRef.current) {
          onChangeRef.current?.({
            ...valueRef.current,
            value: nextItems,
          });
        }
      } else {
        const nextItem = valueRef.current.options?.find((item) => item.value === checkedValue);
        if (nextItem && value.key == 'fileextname') {
          onChangeRef.current?.({
            ...valueRef.current,
            value: nextItem.value,
          });
        } else if(nextItem) {
          onChangeRef.current?.({
            ...valueRef.current,
            value: [nextItem],
          });
        }
      }
    },
    [onChange, mode],
  );

  const nextValue = useMemo(() => {
    if (!value?.value) return;
    if (mode === 'multiple') {
      return value.value.map((item: Option) => item.value);
    }
    
    if (Array.isArray(value.value)) {
      return value.value[0].value;
    } else {
      return value.value
    }

  }, [value, mode]);


  return (
    <Select
      dropdownClassName='selectSecurity'
      value={nextValue}
      mode={mode}
      style={{ width: '100%' }}
      onChange={onChangeHandle}
      getPopupContainer={() => document.body}
      placeholder={getMessage('SearchEngine.pleaseInput')}
    >
      {(valueRef.current?.options || []).map((item) => {
        const checked =
          mode === 'multiple'
            ? !!value?.options?.find?.((v) => v.value === item.value)
            : value?.[0]?.value === item.value;
        return (
          <Select.Option checked={checked} value={item.value}>
            <TextWidget>{item.text}</TextWidget>
          </Select.Option>
        );
      })}
    </Select>
  );
};

export const CustomInput = ({
  value,
  onChange,
  textarea,
}: {
  value?: SchemaOption;
  onChange?: (value: SchemaOption) => void;
  textarea?: boolean;
}) => {
  const onChangeRef = useRef(onChange);
  onChangeRef.current = onChange;
  const valueRef = useRef(value);
  valueRef.current = value;

  const onChangeHandle = useCallback((e) => {
    // if (e.target.value) {
    //   onChangeRef.current?.({ ...valueRef.current, value: e.target.value as string });
    // }
    onChangeRef.current?.({ ...valueRef.current, value: e.target.value as string });
  }, [])

  if (textarea) {
    return (
      <Input.TextArea style={{ width: '100%' }} onChange={onChangeHandle} value={value?.value} />
    );
  }
  return <Input style={{ width: '100%' }} onChange={onChangeHandle} value={value?.value} placeholder={getMessage('SearchEngine.pleaseInput')} />;
};

export const CustomSwitch = ({
  value,
  onChange,
}: {
  value?: SchemaOption;
  onChange?: (value: SchemaOption) => void;
}) => {
  const onChangeRef = useRef(onChange);
  onChangeRef.current = onChange;
  const valueRef = useRef(value);
  valueRef.current = value;

  const onChangeHandle = useCallback((e) => {
    if (valueRef.current) {
      onChangeRef.current?.({ ...valueRef.current, value: e as boolean });
    }
  }, []);

  return <Switch onChange={onChangeHandle} checked={value?.value} />;
};

export const CustomRangePicker = ({
  value,
  onChange,
}: {
  value?: SchemaOption;
  onChange?: (value: SchemaOption) => void;
}) => {
  const newValue = useMemo(() => {
    const [start, end] = value?.value?.split?.('$$') || [];
    const result = [];
    if (start) {
      result[0] = start ? moment(start) : undefined;
    }
    if (end) {
      result[1] = end ? moment(end) : undefined;
    }
    return result as [any, any];
  }, [value?.value]);

  const onChangeHandle = useCallback(
    (e) => {
      const [startTime, endTime] = e || [];
      //  @ts-ignore
      onChange?.({
        ...value,
        value: !(e || []).length
          ? ''
          : `${startTime?.format?.('YYYY-MM-DD') || ''}$$${endTime?.format?.('YYYY-MM-DD') || ''}`,
      });
    },
    [onChange],
  );
  const locale = useMemo(() => {
    const _lang = GlobalRegistry.getDesignerLanguage();
    return commonLang[_lang?.toLocaleLowerCase()?.replace('-', '_') as keyof typeof commonLang || 'zh_cn'];
  }, [GlobalRegistry.getDesignerLanguage()]);

  return (
    <div>
      {/* @ts-ignore */}
      <ConfigProvider locale={locale}>
        <DatePicker.RangePicker
          style={{ width: '100%' }}
          value={newValue}
          onChange={onChangeHandle}
          placeholder={[
            getMessage('SearchEngine.startTime'),
            getMessage('SearchEngine.endTime'),
          ]}
        />
      </ConfigProvider>
    </div>
  );
};

interface CustomSelectFileOrFolderProps extends SelectFolderProps {
  value?: SchemaOption;
  onChange?: (value: SchemaOption) => void;
  searchEngineData: any
}
export const CustomSelectFileOrFolder = ({ value, onChange, searchEngineData, ...rest }: CustomSelectFileOrFolderProps) => {
  const onChangeRef = useRef(onChange);
  onChangeRef.current = onChange;
  const valueRef = useRef(value);
  valueRef.current = value;

  const onChangeHandle = useCallback((e) => {
    if (valueRef.current) {
      onChangeRef.current?.(e);
    }
  }, []);
  const inbiz = useInbiz()
  const { selectShowTab, showTeam, showPerson } = useSearchUIState()
  const { configEvents } = useConfigEventsApi();
  const directoryParams = {
    PageIndex: 1,
    PageSize: 10,
    IndexName: selectShowTab?.isFile ? "file" : 'folder',
    KeyWord: '*',
    SearchWhere: '',
    SearchFields: '',
    ExcludesFields: '',
    HighlightField: '',
    Sort: '',
    Order: 'desc',
    groupNum: '',
    ModuleName: '',
    PreTags: "<span style='color:var(--search-color)'>",
    PostTags: '</span>',
    IsFuzzySearch: true,
    FuzzyFields: '',
    Mark: '',
    SecondaryWord: '',
    IsSynonymSearch: false,
    categorySearchWhere: ''
  }
  const pathkey = selectShowTab?.isFile ? "filepath" : 'folderpath'
  return <BelongDirectory
    params={directoryParams}
    configEvents={configEvents}
    topPersonalFolderId={inbiz.userInfo.topPersonalFolderId}
    pathkey={pathkey}
    showTeam={showTeam}
    showPerson={showPerson}
    config={{ resultsSearchCriteria: '' }}
    searchEngineData={searchEngineData}
    value={value}
    onChange={onChangeHandle}
    advancedSearch
  />
};

export const CustomMemberSelect = ({
  value,
  onChange,
  ...rest
}: {
  value?: SchemaOption;
  onChange?: (value: SchemaOption) => void;
  config: {
    tabs: string[];
  };
}) => {
  const valueRef = useRef(value);
  if (value && value?.key) {
    // 解决弹框选择， value丢失问题
    // @ts-ignore
    valueRef.current = value;
  }
  const onChangeHandle = useCallback(
    (e) => {
      // @ts-ignore
      onChange?.({ ...(value || valueRef.current), value: e });
    },
    [onChange, value],
  );
  // @ts-ignore
  return (
    <MemberSelect
      {...rest}
      multiple={false}
      tabs={['user']}
      value={value?.value}
      onChange={onChangeHandle}
      placeholder="EformMemberSelect.lang.searchUserNameToSelect"
    />
  );
};

interface ICustomFileSize extends SelectFolderProps {
  value?: SchemaOption;
  onChange?: (value: SchemaOption) => void;
}

// 文件大小搜索
export const CustomFileSize = ({ value, onChange }: ICustomFileSize) => {
  const handleChange = useCallback(
    (data: number, index: number) => {
      const newValue = [...(value?.value || [])] as [number, number];
      newValue[index] = data;
      onChange?.({ ...value!, value: newValue });
    },
    [value, onChange],
  );
  return (
    <div className="customFileSize">
      <InputNumber value={value?.value?.[0]} min={0} onChange={(value) => handleChange(value, 0)} />
      <span className="toFileSize">
        <TextWidget>SearchEngine.to</TextWidget>
      </span>
      <InputNumber value={value?.value?.[1]} min={0} onChange={(value) => handleChange(value, 1)} />
      <span className="sizeunit"> M </span>
    </div>
  );
};

const ControlTypeFormItem: ForwardRefRenderFunction<InterfaceProps, Props> = (
  props,
  ref,
): ReactElement => {
  const { onRemoveHandle, fields, style, searchEngineData } = props;
  const [form] = Form.useForm();
  const inbiz = useInbiz();
  const [extnameOptions, $extnameOptions] = useState([])
  useImperativeHandle(
    ref,
    () => {
      return {
        onSubmit: async () => {
          return form.validateFields().then((values) => {
            return JSON.parse(JSON.stringify(values));
          });
        },
        reset: () => {
          form.resetFields();
          // 重置后重新设置value
          const initValues = props.defaultFields.reduce((dict, curr) => {
            return {
              ...dict,
              [curr.key]: curr,
            };
          }, {});
          form.setFieldsValue(initValues);
        },
        setValues: (values) => {
          form.setFieldsValue(values);
        },
      };
    },
    [fields, props.defaultFields],
  );

  const selectFolderprops = {
    mode: 'SelectFolder',
    isTpl: false,
    lang: 'zh-CN',
    inbiz,
    value: {},
    searchEngineData
  } as unknown as SelectFolderProps;

  useEffect(() => {
    if (fields) {
      const initValues = fields?.reduce?.((dict, curr) => {
        return {
          ...dict,
          [curr.key]: curr,
        };
      }, {});
      form.setFieldsValue(initValues);
    }
  }, [fields]);

  const getfiletypes = () => {
    getFiletypes().then(res => {
      if (res.result && res.result.length > 0) {
        const types = res.result.map(item => {
          return {
            ...item,
            label: item.FileExtNameTxt,
            text: item.FileExtNameTxt,
            value: formatTypes(item)
          }
        })
        $extnameOptions(types)
      }
    })
  }

  useEffect(() => {  
    getfiletypes()
  }, [])

  return (
    <Form
      colon={false}
      form={form}
      labelCol={{ span: 6 }}
      className={cn('render-form-wraper', {
        [`render-form-wraper-style2`]: style === 'style2',
      })}
    >
      {fields?.map?.((field, index) => {
        if (field.controlType === 'edoc2Textbox') {
          return (
            <ItemWithRemoveButton
              onRemoveHandle={onRemoveHandle}
              field={field}
              key={field.key + '_' + index}
            >
              <CustomInput />
            </ItemWithRemoveButton>
          );
        }
        if (field.controlType === 'edoc2SelectFolder') {
          return (
            <ItemWithRemoveButton
              onRemoveHandle={onRemoveHandle}
              field={field}
              key={field.key + '_' + index}
            >
              <CustomSelectFileOrFolder {...selectFolderprops} />
            </ItemWithRemoveButton>
          );
        }
        if (field.controlType === 'edoc2SelectMember') {
          return (
            <ItemWithRemoveButton
              onRemoveHandle={onRemoveHandle}
              field={field}
              key={field.key + '_' + index}
            >
              <CustomMemberSelect config={{ tabs: ['user'] }} />
            </ItemWithRemoveButton>
          );
        }
        if (field.controlType === 'edoc2Date') {
          return (
            <ItemWithRemoveButton
              onRemoveHandle={onRemoveHandle}
              field={field}
              key={field.key + '_' + index}
            >
              <CustomRangePicker />
            </ItemWithRemoveButton>
          );
        }
        if (field.controlType === 'edoc2Selectbox' && field.mode === 'singleSelectbox') {
          return (
            <ItemWithRemoveButton
              onRemoveHandle={onRemoveHandle}
              field={field}
              key={field.key + '_' + index}
            >
              <CustomSelect extnameOptions={extnameOptions}/>
            </ItemWithRemoveButton>
          );
        }
        if (field.controlType === 'edoc2Selectbox' && field.mode === 'multipleSelectbox') {
          return (
            <ItemWithRemoveButton
              onRemoveHandle={onRemoveHandle}
              field={field}
              key={field.key + '_' + index}
            >
              <CustomSelect mode="multiple" />
            </ItemWithRemoveButton>
          );
        }
        if (field.controlType === 'edoc2Selectbox' && field.mode === 'single') {
          return (
            <ItemWithRemoveButton
              onRemoveHandle={onRemoveHandle}
              field={field}
              key={field.key + '_' + index}
            >
              <CustomRadio />
            </ItemWithRemoveButton>
          );
        }
        if (field.controlType === 'edoc2Selectbox' && field.mode === 'multiple') {
          return (
            <ItemWithRemoveButton
              onRemoveHandle={onRemoveHandle}
              field={field}
              key={field.key + '_' + index}
            >
              <CustomCheckBox />
            </ItemWithRemoveButton>
          );
        }
        if (field.controlType === 'edoc2Number') {
          return (
            <ItemWithRemoveButton
              onRemoveHandle={onRemoveHandle}
              field={field}
              key={field.key + '_' + index}
            >
              <NumberItem />
            </ItemWithRemoveButton>
          );
        }
        if (field.controlType === 'edoc2TextArea') {
          return (
            <ItemWithRemoveButton
              onRemoveHandle={onRemoveHandle}
              field={field}
              key={field.key + '_' + index}
            >
              <CustomInput textarea />
            </ItemWithRemoveButton>
          );
        }
        if (field.controlType === 'edoc2RichText') {
          return (
            <ItemWithRemoveButton
              onRemoveHandle={onRemoveHandle}
              field={field}
              key={field.key + '_' + index}
            >
              <CustomInput textarea />
            </ItemWithRemoveButton>
          );
        }
        if (field.controlType === 'edoc2Switch') {
          return (
            <ItemWithRemoveButton
              onRemoveHandle={onRemoveHandle}
              field={field}
              key={field.key + '_' + index}
            >
              <CustomSwitch />
            </ItemWithRemoveButton>
          );
        }
        if (field.controlType === 'edoc2FileSize') {
          return (
            <ItemWithRemoveButton
              onRemoveHandle={onRemoveHandle}
              field={field}
              key={field.key + '_' + index}
            >
              <CustomFileSize />
            </ItemWithRemoveButton>
          );
        }
        return null;
      })}
    </Form>
  );
};

export default forwardRef(ControlTypeFormItem);
